; This module initializes the microcontroller then executes MAIN forever
;
CSEG
Reset:
MOV SP, #235 ; Initialize the Stack
MOV PageReg, #7FH ; Allows MOVX Ri to access EZ-USB memory
MOV R0, #Low(USBControl) ; Simulate a disconnect
MOVX A, @R0
ANL A, #11110011b ; Clear DISCON, DISCOE
MOVX @R0, A
CALL Wait100msec ; Give the host time to react
MOVX A, @R0 ; Reconnect with this new identity
ORL A, #00000110b ; Set DISCOE to enable pullup resistor
MOVX @R0, A ; Set RENUM so that 8051 handles USB requests
CLR A
MOV FLAGS, A ; Start in Default state
InitializeMsecCounter:
INC A ; = 1
MOV Expired_Time, A
MOV Msec_counter, A
InitializeIOSystem: ; Work around the dScope monitor I/O needs
; Setup Port A as 8-bit OUTPUT port (no alternate functions)
; Setup an 8-bit INPUT port using PortB_Bits [7:4] and PortC_Bits[3:0]
; Assume a pre-existing configuration (ie dScope)
MOV R0, #LOW(PortA_Config) ; PageReg = 7F = HIGH(PortA_Config)
CLR A
MOVX @R0, A ; No alternate functions
MOV R1, #LOW(PortA_OE)
CPL A ; = 0FFH
MOVX @R1, A ; Enable PortA for Output
INC R0 ; Point to PortB_Config
INC R1 ; Point to PortB_OE
MOVX A, @R0 ; Get current configuration
ANL A, #0FH
MOVX @R0, A ; No alternate functions on upper nibble
MOVX A, @R1 ; Get current configuration
ORL A, #0F0H
MOVX @R1, A ; Enable PortB_Bits[7:4] for Output
INC R0 ; Point to PortC_Config
INC R1 ; Point to PortC_OE
MOVX A, @R0 ; Get current configuration
ANL A, #0F0H
MOVX @R0, A ; No alternate functions on lower nibble
MOVX A, @R1 ; Get current configuration
ORL A, #0FH
MOVX @R1, A ; Enable PortC_Bits[3:0] for Output
InitializeThermometers:
MOV R0, #Low(PortA_Out) ; Do all six at the same time
MOV A, #00000100b ; Select pattern
ILoop: MOV R6, A
MOV A, #00000001b ; Port A idle state
ORL A, R6
MOVX @R0, A ; Select one of the thermometers
MOV R5, #0CH ; Configure command
CALL SendByte
MOV R5, #00001010b ; Set CPU mode and continuous conversion
CALL SendByte
MOV R2, A ; Save A
MOV A, #00000001b ; Port A idle state
MOVX @R0, A
MOV Temp, #20
CALL Wait1msec ; Wait for write to complete
MOV A, R2 ; Restore A
MOV R5, #0EEH ; Start temperature conversion command
CALL SendByte
XCH A, R6
CLR C ; Need to zero fill
RLC A
JNZ ILoop
InitializeInterruptSystem: ; First initialize the USB level
CLR A
MOV R0, #LOW(IN07IEN)
MOVX @R0, A ; Disable interrupts from IN Endpoints 0-7
INC R0
MOVX @R0, A ; Disable interrupts from OUT Endpoints 0-7
INC R0
MOV A, #00000011b
MOVX @R0, A ; Enable (Resume, Suspend,) SOF and SUDAV INTs
INC R0
MOV A, #00000001b
MOVX @R0, A ; Enable Auto Vectoring for USB interrupts
; Now enable the main level
MOV EIE, #00000001b ; Enable INT2 = USB Interrupt (only)
MOV EI, #11000000b ; Enable interrupt subsystem (and Ser1 for dScope)
; Initialization Complete.
;
MAIN:
NOP ; Not much of a main loop for this example
JMP MAIN ; All actions are initiated by interrupts
; We are a slave, we wait to be told what to do
Wait100msec:
MOV Temp, #100
Wait1msec: ; A delay loop
MOV DPTR, #-1200
More: INC DPTR ; 3 cycles
MOV A, DPL ; + 2
ORL A, DPH ; + 2
JNZ More ; + 3 = 10 cycles x 1200 = 1msec
DJNZ Temp, Wait1msec
RET
ProcessOutputReport: ; A Report has just been received
; The report is 12 bytes long in this example
; It contains a new limits values
MOV DPTR, #EP0OutBuffer ; Point to the Report
MOV R0, #LimitValues
MOV R7, #12
CopyOR: MOVX A, @DPTR ; Get the Data
MOV @R0, A ; Update the local variable
INC DPTR
INC R0
DJNZ R7, CopyOR
RET
CreateInputReport: ; Called from TIMER which detected the need
; The report is seven bytes long in this example
; It contains the temperature readings
MOV DPTR, #IN1ByteCount
MOV A, #7
MOVX @DPTR, A ; Endpoint 1 now 'armed', next IN will get data
RET